home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / misc / unix / tracker_4_3.lzh / tracker / open.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-13  |  5.8 KB  |  312 lines

  1. /* open.c 
  2.     vi:se ts=3 sw=3:
  3.  */
  4.  
  5. /* Magic open file: path lookup and transparent decompression */
  6.  
  7. /* $Id: open.c,v 4.1 1994/01/12 16:11:07 espie Exp espie $ 
  8.  * $Log: open.c,v $
  9.  * Revision 4.1  1994/01/12  16:11:07  espie
  10.  * Last minute changes.
  11.  *
  12.  * Revision 4.0  1994/01/11  17:50:46  espie
  13.  * A little more abstract, should work better
  14.  *
  15.  * Revision 1.6  1994/01/09  17:36:22  Espie
  16.  * Generalized open.c.
  17.  *
  18.  * Revision 1.5  1994/01/08  19:43:57  Espie
  19.  * Better amiga patterns.
  20.  *
  21.  * Revision 1.4  1994/01/05  16:10:49  Espie
  22.  * *** empty log message ***
  23.  *
  24.  * Revision 1.3  1994/01/05  14:54:09  Espie
  25.  * *** empty log message ***
  26.  *
  27.  * Revision 1.2  1994/01/05  13:50:43  Espie
  28.  * Cosmetic change.
  29.  *
  30.  * Revision 1.1  1993/12/26  00:55:53  Espie
  31.  * Initial revision
  32.  *
  33.  * Revision 3.12  1993/12/04  16:12:50  espie
  34.  * New semantics.
  35.  *
  36.  * Revision 3.11  1993/12/02  15:45:33  espie
  37.  * Simpler.
  38.  *
  39.  * Revision 3.10  1993/11/27  17:29:53  espie
  40.  * Suppressed stupid abstraction.
  41.  *
  42.  * Revision 3.9  1993/11/17  15:31:16  espie
  43.  * *** empty log message ***
  44.  *
  45.  * Revision 3.8  1993/11/11  20:00:03  espie
  46.  * Amiga support.
  47.  *
  48.  * Revision 3.7  1993/08/17  16:53:09  espie
  49.  * New gzip suffix.
  50.  *
  51.  * Revision 3.3  1993/07/14  16:33:41  espie
  52.  * Added gzip/shorten.
  53.  *
  54.  * Revision 3.2  1992/12/03  15:00:50  espie
  55.  * restore stty.
  56.  *
  57.  * Revision 3.1  1992/11/19  20:44:47  espie
  58.  * Protracker commands.
  59.  *
  60.  * Revision 3.0  1992/11/18  16:08:05  espie
  61.  * New release.
  62.  *
  63.  * Revision 1.5  1992/11/01  13:10:06  espie
  64.  * Cleaned up path handler, and some more bugs.
  65.  * Check for size now.
  66.  * Added path support. Transparent interface. We look up through the file
  67.  * list, which is small anyway.
  68.  */
  69.  
  70. #include "defs.h"
  71.  
  72. #include <stdio.h>
  73. #include <string.h>
  74. #include <ctype.h>
  75. #ifdef MALLOC_NOT_IN_STDLIB
  76. #include <malloc.h>
  77. #else
  78. #include <stdlib.h>
  79. #endif
  80.  
  81. #include "extern.h"
  82.  
  83. ID("$Id: open.c,v 4.1 1994/01/12 16:11:07 espie Exp espie $")
  84.  
  85. extern int error;
  86.  
  87. struct exfile
  88.    {
  89.    FILE *handle;
  90.    void (*close)P((struct exfile *f));
  91.    void (*rewind)P((struct exfile *f));
  92.    int (*getcar)P((struct exfile *f));
  93.    int (*tell)P((struct exfile *f));
  94.    int pos;
  95.    };
  96.  
  97. LOCAL int do_getchar(f)
  98. struct exfile *f;
  99.    {
  100.    int c;
  101.  
  102.    if ((c = fgetc(f->handle)) == EOF)
  103.       error = FILE_TOO_SHORT;
  104.    else
  105.       f->pos++;
  106.    return c;
  107.    }
  108.  
  109. LOCAL int do_tell(f)
  110. struct exfile *f;
  111.    {
  112.    return f->pos;
  113.    }
  114.  
  115. LOCAL void do_pclose(f)
  116. struct exfile *f;
  117.    {
  118.    pclose(f->handle);
  119.    }
  120.  
  121. LOCAL void do_fclose(f)
  122. struct exfile *f;
  123.    {
  124.    fclose(f->handle);
  125.    }
  126.  
  127.    
  128. /* compression methods we do know about.
  129.  * Important restriction: for the time being, the output
  130.  * must be a single module.
  131.  */
  132.  
  133. LOCAL struct compression_method
  134.    {
  135.    char *extension;
  136.    char *command;
  137.    } comp_table[] =
  138.    {
  139.    ".czip", "unczip %s",
  140.    ".gz",   "gzip -dc %s",
  141. #ifdef GZIP
  142.    ".z", "gzip -dc %s",
  143. #else
  144.     ".Z",   "zcat %s",
  145. #endif
  146.    ".s", "shorten -x %s -",
  147.    ".shn",  "shorten -x %s -",
  148.    ".zoo", "zoo xpq %s",
  149. #ifdef AMIGA
  150.    ".lzh", "lha -q p \"%s\"",
  151.    ".lha", "lha -q p \"%s\"",
  152. #else
  153.    ".lzh", "lha pq %s",
  154.    ".lha", "lha pq %s",
  155. #endif
  156.    ".zip", "unzip -pq %s",
  157.    ".arc", "arc pn %s",
  158.    NULL,   NULL
  159.    };
  160.  
  161. /***
  162.  *
  163.  *  Handling extensions.
  164.  *
  165.  ***/
  166.  
  167. LOCAL boolean check_ext(s, ext)
  168. char *s, *ext;
  169.    {
  170.    int ext_len, s_len;
  171.    char *c;
  172.  
  173.    ext_len = strlen(ext);
  174.    s_len = strlen(s);
  175.    if (s_len < ext_len)
  176.       return FALSE;
  177.    for (c = s + s_len - ext_len; *c; c++, ext++)
  178.       if (tolower(*c) != tolower(*ext))
  179.          return FALSE;
  180.    return TRUE;
  181.    }
  182.  
  183. LOCAL boolean exist_file(fname)
  184. char *fname;
  185.    {
  186.    FILE *temp;
  187.  
  188.    temp = fopen(fname, "r");
  189.    if (temp)
  190.       {
  191.       fclose(temp);
  192.       return TRUE;
  193.       }
  194.    else
  195.       return FALSE;
  196.    }
  197.  
  198. #ifndef MAXPATHLEN
  199. #define MAXPATHLEN 350
  200. #endif
  201.  
  202. LOCAL char *find_file(fname, path)
  203. char *fname;
  204. char *path;
  205.    {
  206.    char *sep;
  207.    static char buffer[MAXPATHLEN];
  208.    int len;
  209.  
  210.       /* first, check the current directory */
  211.    if (exist_file(fname))
  212.       return fname;
  213.    while(path)
  214.       {
  215.       sep = strchr(path, ':');
  216.       if (sep)
  217.          len = sep - path;
  218.       else
  219.          len = strlen(path);
  220.       if (len < MAXPATHLEN)
  221.          {
  222.          strncpy(buffer, path, len);
  223.          buffer[len] = '/';
  224.          if (len + strlen(fname) < MAXPATHLEN - 5)
  225.             {
  226.             strcpy(buffer + len + 1, fname);
  227.             puts(buffer);
  228.             if (exist_file(buffer))
  229.                return buffer;
  230.             }
  231.          }
  232.       if (sep)
  233.          path = sep + 1;
  234.       else
  235.          return NULL;
  236.       }
  237.    return NULL;
  238.    }
  239.  
  240. FILE *file_handle(f)
  241. struct exfile *f;
  242.    {
  243.    return f->handle;
  244.    }
  245.  
  246. int getc_file(f)
  247. struct exfile *f;
  248.    {
  249.    return (*f->getcar)(f);
  250.    }
  251.  
  252. int tell_file(f)
  253. struct exfile *f;
  254.    {
  255.    return (*f->tell)(f);
  256.    }
  257.  
  258. struct exfile *open_file(fname, mode, path)
  259. char *fname;
  260. char *mode; /* right now, only mode "r" is supported */
  261. char *path; 
  262.    {
  263.    struct exfile *new;
  264.    struct compression_method *comp;
  265.  
  266.    if (mode[0] != 'r' || mode[1] != 0)
  267.       return NULL;
  268.     
  269.    new = (struct exfile *)malloc(sizeof(struct exfile));
  270.    if (!new)
  271.       return NULL;
  272.  
  273.    new->getcar = do_getchar;
  274.    new->tell = do_tell;
  275.    new->pos = 0;
  276.    fname = find_file(fname, path);
  277.    if (!fname)
  278.       return NULL;
  279.    for (comp = comp_table; comp->extension; comp++)
  280.       if (check_ext(fname, comp->extension))
  281.          {
  282.          char pipe[MAXPATHLEN + 25];
  283.  
  284.          sprintf(pipe, comp->command, fname);
  285.          new->close = do_pclose;
  286.          if (new->handle = popen(pipe, "r"))
  287.             return new;
  288.          else
  289.             {
  290.             free(new);
  291.             return NULL;
  292.             }
  293.          }
  294.    new->close = do_fclose;
  295.    if (new->handle = fopen(fname, "r"))
  296.       return new;
  297.    else
  298.       {
  299.       free(new);
  300.       return NULL;
  301.       }
  302.    }
  303.  
  304.  
  305. void close_file(file)
  306. struct exfile *file;
  307.    {
  308.    (*file->close)(file);
  309.    free(file);
  310.    }
  311.  
  312.